﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static DB_BYS1215.DBSCAN;

namespace DB_BYS1215
{
    class DBSCAN
    {
        /// <summary>
        /// point 类
        /// </summary>
        public class point
        {
            public float x, y, z, m, n;
            public int cluster = 0, pointType = 1, pts = 0, visited = 0;
            public List<int> corepts = new List<int>();
            public point(float a, float b, float c, float d, float e, int f)
            {
                x = a;
                y = b;
                z = c;
                m = d;
                n = e;
                cluster = f;
            }
        }
    /// <summary>
    /// 字符串转换为浮点数函数
    /// </summary>
    /// <param name="i">要转换的字符串</param>
    /// <returns></returns>
    public float stringToFloat(string i)
        {
            float score = 0;
            score = float.Parse(i);
            return score;
        }
        public int stringToint(string i)
        {
            int score = 0;
            score = int.Parse(i);
            return score;
        }
        List<point> data = new List<point>();
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <returns></returns>
        public List<point> Get_data()
        {
            FileStream fs = new FileStream("E:\\data.txt", FileMode.Open, FileAccess.Read);
            StreamReader sr = new StreamReader(fs);
            string str = sr.ReadLine();
            int i = 1;
            while (str!=null)
            {
                string[] xu = new String[15];
                xu = str.Split(',');
                for (int j = 0; j <= 14; j++)
                {
                    if (xu[j] == null || xu[j] == "收"||xu[j]=="")
                        xu[j] = Convert.ToString(0);
                }
                float ser = stringToFloat(xu[6])- stringToFloat(xu[5]);
                float one = stringToFloat(xu[8])- stringToFloat(xu[7]);
                float two = stringToFloat(xu[10])- stringToFloat(xu[9]);
                float three = stringToFloat(xu[12])- stringToFloat(xu[11]);
                float four = stringToFloat(xu[14])- stringToFloat(xu[13]);
                point p = new point(ser, one, two, three, four, i++);
                data.Add(p);
                str = sr.ReadLine();
            }
            fs.Close();
            sr.Close();
            return data;
        }
        public int DBresult()
        {
            FileStream file = new FileStream("E:\\DBoutput.txt", FileMode.Open);
            StreamReader sr = new StreamReader(file);
            string str = sr.ReadLine();
            String[] count = new string[10000];
            int c = 0;
            int d = 0;
            while (str != null)
            {
                string[] a = new String[6];
                a = str.Split(',');
                count[d] = a[5];
                if (a[0] == "tab")
                    break;
                d++;
                str = sr.ReadLine();
            }
            for (int i = 1; i <= count.Length-1; i++)
            {
                int a = 0;
                if (count[i] == "tab")
                    break;
                for (int j = i - 1; j >= 0; j--)
                {
                    if (count[i] == count[j])
                    {
                        break;
                    }
                    a++;
                }
                if (a == i)
                {
                    c++;
                }
            }
            sr.Close();
            file.Close();
            return c+1;
        }
        public int DBnumber()
        {
            FileStream file = new FileStream("E:\\DBoutput.txt", FileMode.Open);
            StreamReader sr = new StreamReader(file);
            string str = sr.ReadLine();
            int i=-1;
            while (str != null)
            {
                i++;
                str = sr.ReadLine();
            }
            file.Close();
            sr.Close();
            return i;
        }
    }
    class dbal
    {
        /// <summary>
        /// 计算两点间的距离
        /// </summary>
        /// <param name="a">第一个点</param>
        /// <param name="b">第二个点</param>
        /// <returns></returns>
        public float squareDistance(point a, point b)
        {
            return (float)Math.Sqrt(100*(a.x - b.x) * (a.x - b.x) + 100*(a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z) + 100*(a.m - b.m) * (a.m - b.m) + (a.n - b.n) * (a.n - b.n));
        }
        public void DBSCAN(List<point> dataset, float Eps, int MinPts)
        {
            int len = dataset.Count();
            for (int i = 0; i < len; i++)
            {
                for (int j = i + 1; j < len; j++)
                {
                    if (squareDistance(dataset[i], dataset[j]) < Eps)
                    {
                        dataset[i].pts++;
                        dataset[j].pts++;
                    }
                }
            }//计算一点在半径内其他点的个数
            List<point> corePoint = new List<point>();
            for (int i = 0; i < len; i++)
            {
                if (dataset[i].pts >= MinPts)
                {
                    dataset[i].pointType = 3;
                    corePoint.Add(dataset[i]);
                }
            }//找到所有核心点
            for (int i = 0; i < corePoint.Count; i++)
            {
                for (int j = i + 1; j < corePoint.Count; j++)
                {
                    if (squareDistance(corePoint[i], corePoint[j]) < Eps)
                    {
                        corePoint[i].corepts.Add(j);
                        corePoint[j].corepts.Add(i);
                    }
                }
            }//找到同一簇的核心点
            for (int i = 0; i < corePoint.Count; i++)
            {
                Stack<point> ps = new Stack<point>();
                if (corePoint[i].visited == 1)
                    continue;
                ps.Push(corePoint[i]);
                point v;
                while (ps.Count != 0)
                {
                    v = ps.Pop();
                    v.visited = 1;
                    for (int j = 0; j < v.corepts.Count; j++)
                    {
                        if (corePoint[v.corepts[j]].visited == 1) continue;
                        corePoint[v.corepts[j]].cluster = corePoint[i].cluster;
                        corePoint[v.corepts[j]].visited = 1;
                        ps.Push(corePoint[v.corepts[j]]);
                    }
                }
            }//深度优先遍历所有核心点
            for (int i = 0; i < len; i++)
            {
                if (dataset[i].pointType == 3)
                    continue;
                for (int j = 0; j < corePoint.Count; j++)
                {
                    if (squareDistance(dataset[i], corePoint[j]) < Eps)
                    {
                        dataset[i].pointType = 2;
                        dataset[i].cluster = corePoint[j].cluster;
                        break;
                    }
                }
            }
            FileStream fs = new FileStream("E:\\DBoutput.txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            for (int i = 0; i < len; i++)
            {
                if (dataset[i].pointType == 2)
                {
                    sw.Write(dataset[i].x);
                    sw.Write(",");
                    sw.Write(dataset[i].y);
                    sw.Write(",");
                    sw.Write(dataset[i].z);
                    sw.Write(",");
                    sw.Write(dataset[i].m);
                    sw.Write(",");
                    sw.Write(dataset[i].n);
                    sw.Write(",");
                    sw.Write(dataset[i].cluster);
                    sw.Write(",");
                    sw.WriteLine("非核心点");
                }
            }
            for (int i = 0; i < corePoint.Count(); i++)
            {
                if (dataset[i].pointType == 3)
                {
                    sw.Write(dataset[i].x);
                    sw.Write(",");
                    sw.Write(dataset[i].y);
                    sw.Write(",");
                    sw.Write(dataset[i].z);
                    sw.Write(",");
                    sw.Write(dataset[i].m);
                    sw.Write(",");
                    sw.Write(dataset[i].n);
                    sw.Write(",");
                    sw.Write(dataset[i].cluster);
                    sw.Write(",");
                    sw.WriteLine("核心点");
                }
                if (i == corePoint.Count() - 1)
                {
                    sw.Write("tab");sw.Write(",");
                    sw.Write("tab"); sw.Write(",");
                    sw.Write("tab"); sw.Write(",");
                    sw.Write("tab"); sw.Write(",");
                    sw.Write("tab"); sw.Write(",");
                    sw.Write("tab");
                }
            }
            sw.Close();
            fs.Close();
        }
    }
}
